/*
 * 1, 新建实例, 参数 el, width, height 必填
 * 2, 可用于, 鼠标滚轮放大缩小,拖动移动
 * 3, 也可用于, 按钮放大,缩小,旋转,还原
 **/
class Scale {
  constructor({
    el,
    width,
    height,
    isMousewheel = true,
    maxScale = 10,
    minScale = 0.5
  }) {
    this.width = width;
    this.height = height;
    this.el = el;
    this.maxScale = maxScale;
    this.minScale = minScale;
    this.isMousewheel = isMousewheel;
    this.parentNodeEl = el.parentNode;
    this.offSetX = 0;
    this.offSetY = 0;
    this.moveFlag = false;
    this.scale = 1;
    // 第一个点坐标
    this.point = { x: 0, y: 0 };
    // 相对于上一次pointermove移动差值
    this.diff = { x: 0, y: 0 };
    // 用于计算diff
    this.lastPointermove = { x: 0, y: 0 };
    this.rotateDeg = 0;
    this.oX = 0;
    this.oY = 0;
  }

  init() {
    this.setStyle();
    this.el.style.width = this.width + "px";
    this.el.style.height = this.height + "px";

    this.el.style.userSelect = "none";

    this.parentNodeEl.style.overflow = "hidden";
    this.parentNodeEl.style.width = this.width + "px";
    this.parentNodeEl.style.height = this.height + "px";

    if (this.isMousewheel) {
      this.el.addEventListener(
        "mousewheel",
        this.mouseWeelZoom.bind(this),
        false
      );
    }

    this.el.addEventListener("mousedown", this.mounseDown.bind(this), false);
    this.el.addEventListener("mouseup", this.mouseUp.bind(this), false);
  }

  stop() {
    if (this.isMousewheel) {
      this.el.removeEventListener(
        "mousewheel",
        this.mouseWeelZoom.bind(this),
        false
      );
    }
    this.el.removeEventListener("mousedown", this.mounseDown.bind(this), false);
    this.el.removeEventListener("mouseup", this.mouseUp.bind(this), false);
  }

  reset() {
    this.scale = 1;
    this.offSetX = 0;
    this.offSetY = 0;
    this.rotateDeg = 0;
    this.setStyle();
  }

  rotate() {
    this.rotateDeg += 90;

    if (this.rotateDeg >= 360) {
      this.rotateDeg = 0;
    }

    this.setStyle();
  }

  setStyle() {
    this.el.style.transform = `translate3d(${this.offSetX}px, ${this.offSetY}px, 0) scale(${this.scale}) rotate(${this.rotateDeg}deg)`;
  }

  // 放大
  enlarged(scale) {
    this.scale += scale;

    if (this.scale > this.maxScale) {
      this.scale = this.maxScale;
    }

    this.setStyle();
  }

  // 缩小
  reduce(scale) {
    this.scale -= scale;

    if (this.scale < this.minScale) {
      this.scale = this.minScale;
    }

    this.setStyle();
  }

  // 缩放
  mouseWeelZoom(e) {
    let ratio = 1.1;
    // 缩小
    if (e.deltaY > 0) {
      ratio = 1 / 1.1;
    }
    // 限制缩放倍数
    const _scale = this.scale * ratio;

    if (_scale > this.maxScale) {
      ratio = this.maxScale / this.scale;
      this.scale = this.maxScale;
    } else if (_scale < this.minScale) {
      ratio = this.minScale / this.scale;
      this.scale = this.minScale;
    } else {
      this.scale = _scale;
    }

    const deltaY = e.deltaY;
    if (deltaY < 0) {
      this.scale += 0.2;
    } else {
      if (this.scale < 1.2) return;
      this.scale -= 0.2;
    }
    const oX = (e.offsetX / this.width) * 100;
    const oY = (e.offsetY / this.height) * 100;

    if (Math.abs(oX) < 100 || Math.abs(oY) < 100) {
      this.oX = oX;
      this.oY = oY;
      this.el.style.transformOrigin = `${oX}% ${oY}%`;
    }

    this.setStyle();

    e.preventDefault();
  }

  // 鼠标按下
  mounseDown(e) {
    this.moveFlag = true;
    this.point = { x: e.clientX, y: e.clientY };
    this.lastPointermove = { x: e.clientX, y: e.clientY };

    if (this.el) {
      this.el.style.cursor = "move";
      this.el.addEventListener("mousemove", this.mouseMove.bind(this), false);
    }
  }

  //鼠标移动
  mouseMove(e) {
    if (!this.moveFlag) return;
    const current = { x: e.clientX, y: e.clientY };
    this.diff.x = current.x - this.lastPointermove.x;
    this.diff.y = current.y - this.lastPointermove.y;
    this.lastPointermove = { x: current.x, y: current.y };
    this.offSetX += this.diff.x;
    this.offSetY += this.diff.y;

    this.setStyle();
    e.preventDefault();
  }
  // 鼠标弹起
  mouseUp(e) {
    if (!this.moveFlag) return;
    this.moveFlag = false;

    if (this.el) {
      this.el.style.cursor = "";
      this.el.removeEventListener("mousemove", this.mouseMove, false);
    }
  }
}

export default Scale;
